#ifndef XG_DB_CONNECTPOOL_CPP
#define XG_DB_CONNECTPOOL_CPP
////////////////////////////////////////////////////////
#include "../DBConnectPool.h"


DBConnectPool::DBConnectPool()
{
	creator = [&](){
		sp<DBConnect> conn(createConnect());

		if (conn && cfg.charset.length() > 0) conn->setCharset(cfg.charset);

		return conn;
	};
}
sp<DBConnect> DBConnectPool::get()
{
	sp<DBConnect> conn = ResPool<DBConnect>::get();

	if (conn && conn->getErrorCode())
	{
		disable(conn);

		return get();
	}

	return conn;
}
bool DBConnectPool::init(const string& path)
{
	YAMLoader file;

	CHECK_FALSE_RETURN(file.open(path));

	return init(&file);
}
bool DBConnectPool::init(const YAMLoader* file)
{
	if (file == NULL) file = YAMLoader::Instance();

	{
		SpinLocker lk(mtx);

		CHECK_FALSE_RETURN(cfg.load(file));

		file->get("database.maxsize", maxlen);
		file->get("database.timeout", timeout);

		CHECK_FALSE_RETURN(maxlen > 0 && cfg.name.length() > 0);

		vec.clear();
	}

	sp<DBConnect> conn = get();

	CHECK_FALSE_RETURN(conn);

	if (strcmp(conn->getSystemName(), "SQLite") == 0) timeout = 0;

	return true;
}
DBConnectPool* DBConnectPool::Create(const YAMLoader* file)
{
	if (file == NULL) file = YAMLoader::Instance();

	string dllpath = file->get("database.dllpath");

	if (dllpath.empty()) dllpath = GetDefaultLibraryPath(file->get("database.type"));

	sp<DllFile> dll;
	CREATE_DBCONNECTPOOL_FUNC crtfunc = NULL;
	DESTROY_DBCONNECTPOOL_FUNC dsyfunc = NULL;

	if ((dll = DllFile::Get(dllpath)) && dll->read(crtfunc, "CreateDBConnectPool") && dll->read(dsyfunc, "DestroyDBConnectPool"))
	{
		DBConnectPool* dbconnpool = NULL;

		if ((dbconnpool = crtfunc()) == NULL) return dbconnpool;
		if (dbconnpool->init(file)) return dbconnpool;
		
		dsyfunc(dbconnpool);
	}

	return NULL;
}
string DBConnectPool::GetDefaultLibraryPath(const string& type)
{
	string name = stdx::tolower(type);

	if (name.empty()) name = "sqlite";

	return stdx::translate("$CPPWEB_PRODUCT_HOME/dll/libdbx." + name + "pool.so");
}
////////////////////////////////////////////////////////
#endif
